#ifndef REGEX_DFA_H
#define REGEX_DFA_H

#include "Regex/RegexNFA.h"

namespace GxRegex
{
	using namespace GxLibBasic;
	typedef Array<Word> RegexCharTable;
	
	class CharTableGenerator : public Object
	{
	private:
		Array<String> sets;
		RegexCharTable * table;
		int AddSet(String set);
	public:
		Array<RegexCharSet::RegexCharRange> elements;
		CharTableGenerator(RegexCharTable * _table);
		int Generate(Array<RegexCharSet *> & charSets);
	};

	class DFA_Table_Tag
	{
	public:
		bool IsFinal;
		OrderedArray<int, true> TerminalIdentifiers;
		DFA_Table_Tag();
	};

	class DFA_Table : public Object
	{
	public:
		int StateCount;
		int AlphabetSize;
		int ** DFA;
		Array<RefPtr<DFA_Table_Tag>> Tags;
		int StartState;
		RefPtr<RegexCharTable> CharTable;
		DFA_Table();
		~DFA_Table();
	};

	class DFA_Node : public Object
	{
	public:
		int ID;
		bool IsFinal;
		OrderedArray<int, true> TerminalIdentifiers;
		OrderedArray<NFA_Node*> Nodes; 
		Array<DFA_Node *> Translations;
		DFA_Node(int elements);
		bool operator == (const DFA_Node & node);
	};

	class DFA_Graph : public Object
	{
	private:
		Array<RegexCharSet::RegexCharRange> CharElements;
		RefPtr<RegexCharTable> table;
		DFA_Node * startNode;
		Array<RefPtr<DFA_Node>> nodes;
		void CombineCharElements(NFA_Node * node, Array<Word,true> & elem);
	public:
		void Generate(NFA_Graph * nfa);
		String Interpret();
		void ToDfaTable(DFA_Table * dfa);
	};
}

#endif